﻿using System;
using System.Collections.Generic;
using System.IO;

namespace ExRev.Engine.Utils
{
    public class LoggerManager
    {
        public static LoggerManager Instance
        {
            get { return instance; }
        }
        private static LoggerManager instance;

        private List<Logger> loggers = new List<Logger>(10);

        /// <summary>
        /// Count of the registered loggers
        /// </summary>
        public int LoggerCount
        {
            get { return loggers.Count; }
        }

        /// <summary>
        /// Path for all loggers
        /// </summary>
        public string Path
        {
            get { return path; }
            set { path = value; }
        }
        private string path = Directory.GetCurrentDirectory();

        public string[] RegisteredLoggers
        {
            get { return registeredLoggers.ToArray(); }
        }
        private List<string> registeredLoggers = new List<string>(10);

        static LoggerManager()
        {
            instance = new LoggerManager();
        }

        /// <summary>
        /// Registeres a new logger.
        /// The maximum number of possible loggers is 10.
        /// </summary>
        /// <param name="path">Path where the loggers logs to</param>
        /// <returns>Logger is wether correctly registered or an error occured</returns>
        public bool RegisterLogger(Logger.Type type, string name)
        {
            if (registeredLoggers.Count > 10 || registeredLoggers.Contains(name)) {
                return false;
            }

            string fileName;
            FileStream fs = null;

            try {
                switch (type) {
                    case Logger.Type.Html:
                        fileName = name + ".html";
                        break;
                    case Logger.Type.Text:
                        fileName = name + ".txt";
                        break;
                    default:
                        return false;
                }
                fs = File.Create(fileName);
            } catch {
                return false;
            } finally {
                fs.Close();
            }

            registeredLoggers.Add(fileName);

            return true;
        }

        /// <summary>
        /// Returns a Logger for the specified path
        /// </summary>
        /// <param name="path">Path where the logger logs to</param>
        /// <returns>Returns an existing logger or a new logger for the specified path</returns>
        public Logger GetLogger(Logger.Type type, string name)
        {
            string fileName;
            switch (type) {
                case Logger.Type.Html:
                    fileName = name + ".html";
                    break;
                case Logger.Type.Text:
                    fileName = name + ".txt";
                    break;
                default:
                    return null;
            }
            if (!registeredLoggers.Contains(fileName)) {
                throw new LoggerNotRegisteredException(string.Format("Logger {0} is not registered yet", name));
            }

            Logger log = loggers.Find(logger => logger.Name == name);

            if (log == null) {
                switch (type) {
                    case Logger.Type.Text:
                        log = new TextLogger(name, path);
                        break;
                    case Logger.Type.Html:
                        log = new HtmlLogger(name, path);
                        break;
                    default:
                        break;
                }
                loggers.Add(log);
            }

            return log;
        }

        /// <summary>
        /// Checks if requested logger is registered
        /// </summary>
        /// <param name="path">Path of the logger</param>
        /// <returns>Logger is wether registered or not</returns>
        public bool IsLoggerRegistered(Logger.Type type, string name)
        {
            string fileName;

            switch (type) {
                case Logger.Type.Html:
                    fileName = name + ".html";
                    break;
                case Logger.Type.Text:
                    fileName = name + ".txt";
                    break;
                default:
                    return false;
            }
            return registeredLoggers.Contains(fileName);
        }
    }
}
